import React, { useState, useEffect } from 'react';
import { DownSquareOutlined, UpSquareOutlined } from '@ant-design/icons';
import { message, Spin, Timeline } from 'antd';
import { useSetState, useUpdateEffect } from 'ahooks';
import { HttpCode } from '#/utils/contacts.js';
import _ from 'lodash';
// @ts-ignore
import request from '#/utils/requestAbort';
import TRDefault from '@/tool/components/TRTheme/TRDefault';
import type { Argument } from 'classnames';
import type { CSSProperties, ReactNode } from 'react';
import './index.less';
import moment from 'moment';

const defaultMapping: ITjOperateLogMappingType = {
  createTime: 'creationTime',
  creator: 'creator',
  type: 'type',
};

const TjOperateLog: React.FC<ITjOperateLogProps> = (props) => {
  const [req, setReq] = useSetState<Record<string, any>>({
    currentPage: 1,
    pageSize: 50,
  });
  const [loading, setLoading] = useState<boolean>(false);
  const [list, setList] = useState<any[]>([]);

  const query = () => {
    const data = _.merge(req, props.params);
    setLoading(true);
    request(props.queryUrl, { data: data, method: 'POST' })
      .then((res: any) => {
        if (res.statusCode === HttpCode.SUCCESS) {
          setList(res.data);
        } else {
          message.error(res.message);
        }
      })
      .finally(() => {
        setLoading(false);
      });
  };

  const showItem = (item: any, index: number) => {
    const newList = [...list];
    newList[index].show = !newList[index].show;
    setList(newList);
  };

  useEffect(() => {
    query();
  }, []);

  useUpdateEffect(() => {
    query();
  }, [req, props.params]);

  return (
    <div className="tj-operate-log">
      <div className="header-box">{props.header}</div>
      <div className="time-line-box">
        <Spin spinning={loading}>
          {list.length > 0 ? (
            <Timeline>
              {list.map((item: any, index: number) => {
                const mapping = props.mapping || defaultMapping;
                return (
                  <Timeline.Item key={item.id || index} className="item">
                    <div className="head">
                      <div className="left">
                        <div className="date">
                          {moment(item[mapping.createTime]).format('YYYY-MM-DD HH:mm:ss')}
                        </div>
                        <div className="name">{item[mapping.type]}</div>
                        <div className="btn" onClick={() => showItem(item, index)}>
                          {!item.show && <DownSquareOutlined />}
                          {item.show && <UpSquareOutlined />}
                        </div>
                      </div>
                      <div className="right">
                        操作人：<span className="user-name">{item[mapping.creator]}</span>
                      </div>
                    </div>
                    <div className="content" style={{ display: item.show ? 'block' : 'none' }}>
                      {props.content && _.isFunction(props.content) ? props.content(item) : null}
                      {/* <div className="content">
                      {props.content && _.isFunction(props.content) ? props.content(item) : null} */}
                    </div>
                  </Timeline.Item>
                );
              })}
            </Timeline>
          ) : (
            <TRDefault type="empty" />
          )}
        </Spin>
      </div>
    </div>
  );
};

export interface ITjOperateLogMappingType {
  createTime: string;
  creator: string;
  type: string;
}

interface ITjOperateLogProps {
  /**
   * 支持传入行内样式
   */
  style?: CSSProperties;
  /**
   * class
   * 不管传没传，都会有一个 `tj-header` 的 className
   */
  className?: Argument;
  /**
   *  页面顶部，可以做一些比如操作项自定义
   */
  header?: ReactNode;
  /**
   * 查询日志接口文档
   */
  queryUrl: string;
  /**
   * 调用接口查询需要用到的参数，原则上分页类型参数写死，不需要传入与后端商量与其他列表页一致
   */
  params?: Record<string, any>;
  /**
   * 用于映射字段
   */
  mapping?: ITjOperateLogMappingType;
  /**
   * 用于渲染content
   */
  content?: (item: any) => ReactNode;
}

export { TjOperateLog };
